package com.hxzy.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxzy.common.consts.RedisConst;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.exception.ServiceException;
import com.hxzy.common.exception.ShopException;
import com.hxzy.common.vo.R;
import com.hxzy.dto.AdminLoginDTO;
import com.hxzy.entity.ShopDetail;
import com.hxzy.entity.SysUser;
import com.hxzy.mapper.SysUserMapper;
import com.hxzy.service.ShopDetailService;
import com.hxzy.service.SysMenuService;
import com.hxzy.service.SysRoleService;
import com.hxzy.service.SysUserService;
import com.hxzy.vo.AdminLoginVO;
import com.hxzy.vo.SysUserShopVO;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 后台用户表
 */
@Log4j2
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {


    @Autowired
    private ShopDetailService shopDetailService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private RedisTemplate  redisTemplate;

    /**
     * 后台用户登录
     * @param adminLoginDTO
     * @return
     */
    @Override
    public AdminLoginVO login(AdminLoginDTO adminLoginDTO) {
        SysUser dbUser = this.baseMapper.findByAccount(adminLoginDTO.getAccount());
        if (dbUser == null) {
            log.error(adminLoginDTO.getAccount() + "," + AckCode.USER_NOT_FOUND.getMsg());
            throw new ServiceException(AckCode.LOGIN_ACCOUNT_PASSWORD_ERROR);
        }

        //取得redis的键
        String redisKey= RedisConst.getRedisKey(RedisConst.ADMIN_LOGIN_FAILED_KEY, dbUser.getUserId()+"");
        Object  redisValue=   this.redisTemplate.opsForValue().get(redisKey);
        int count=0;
        if(redisValue!=null){
            count= (int) redisValue;
            //不允许再登录了
            if(count>= RedisConst.ADMIN_LOGIN_RETRY_COUNT){
                String msg= StrUtil.format(AckCode.PASSWORD_INCRRENT_RETRY_COUNT.getMsg(), RedisConst.ADMIN_LOGIN_RETRY_COUNT+"",RedisConst.ADMIN_LOGIN_FAILED_LOCK_TIME_MINUTES+"");
                throw new ShopException(msg);
            }
        }

        String bcryptPwd = dbUser.getPassword();
        if (!BCrypt.checkpw(adminLoginDTO.getPassword(), bcryptPwd)) {
            //写入redis中的值
            this.redisTemplate.opsForValue().increment(redisKey);
            //设定一个过期时间
            this.redisTemplate.expire(redisKey, RedisConst.ADMIN_LOGIN_FAILED_LOCK_TIME_MINUTES, TimeUnit.MINUTES);

            //记录错误次数
            count++;
            if(count>= RedisConst.ADMIN_LOGIN_RETRY_COUNT){
                String msg= StrUtil.format(AckCode.PASSWORD_INCRRENT_RETRY_COUNT.getMsg(), RedisConst.ADMIN_LOGIN_RETRY_COUNT+"",RedisConst.ADMIN_LOGIN_FAILED_LOCK_TIME_MINUTES+"");

                throw new ShopException(msg);
            }

            log.error(adminLoginDTO.getAccount() + "," + AckCode.LOGIN_PASSWORD_ERROR.getMsg());

            int retryCount=RedisConst.ADMIN_LOGIN_RETRY_COUNT - count;
            String msg=StrUtil.format(AckCode.USERNAME_PASSWORD_ERROR.getMsg(), retryCount+"", RedisConst.ADMIN_LOGIN_FAILED_LOCK_TIME_MINUTES+"") ;
            throw new ShopException(msg);
        }

        Byte status = dbUser.getStatus();
        if (status.intValue() == 0) {
            log.error(adminLoginDTO.getAccount() + "," + AckCode.DEVICE_BANNED.getMsg());
            throw new ServiceException(AckCode.DEVICE_BANNED);
        }


        //自定义当前用户对象
        SysUserShopVO sysUserShopVO=new SysUserShopVO();
        BeanUtils.copyProperties(dbUser,sysUserShopVO);


        //判断是不是有商户
        if(dbUser.getShopId()!=null){
            ShopDetail shopDetail = this.shopDetailService.getById(dbUser.getShopId());
            if(shopDetail==null){
                throw new ServiceException(AckCode.NOT_FOUND_DATA);
            }
            sysUserShopVO.setShopDetail(shopDetail);
        }

        //自定义数据
        AdminLoginVO  adminLoginVO=new AdminLoginVO();
        adminLoginVO.setSysUserShopVO(sysUserShopVO);

        //查询该用户拥有的角色
        Set<String> roleSet= this.sysRoleService.searchUserOwnRole(dbUser.getUserId());
        adminLoginVO.setRoleSet(roleSet);

        //查询菜单角色
        Set<String> permSet=new HashSet<>();

        //判断是不是超级管理员
        if(adminLoginVO.isSuperMan()){
            permSet.add("*:*:*");
        }else{
            permSet= this.sysMenuService.searchUserOwnPerm(dbUser.getUserId());
        }
        adminLoginVO.setPermsSet(permSet);

        return adminLoginVO;
    }

}
